

function clone(obj) {
    var val = JSON.stringify(obj);
    return JSON.parse(val);
}

function arrayExtend(lst) {
    this.lst = lst;
    return this;
}
if (!Array.prototype._d) {
    Array.prototype._d = function () {
        return new arrayExtend(this);
    };
}
if (!arrayExtend.prototype.isContain) {
    arrayExtend.prototype.isContain = function (val, compareFunc) {
        if (typeof (val) == 'function') {
            compareFunc = val;
            val = null;
        }
        var lst = this.lst;
        for (var i = 0; i < lst.length; i++) {
            if (compareFunc) {
                if (compareFunc.apply(lst[i], [lst[i], val]))
                    return true;
            } else if (lst[i] == val) {
                return true;
            }
        }
        return false;
    }
}
if (!arrayExtend.prototype.remove) {
    arrayExtend.prototype.remove = function (val, compareFunc) {
        var lst = this.lst;
        for (var i = 0; i < lst.length; i++) {
            if (compareFunc) {
                if (compareFunc.apply(lst[i], [lst[i], val])) {
                    lst.splice(i, 1);
                    return true;
                }
            } else {
                if (lst[i] == val) {
                    lst.splice(i, 1);
                    return true;
                }
            }
        }
        return false;
    }
}
if (!arrayExtend.prototype.filter) {
    arrayExtend.prototype.filter = function (filterFunc) {
        var res = [];
        var lst = this.lst;
        for (var i = 0; i < lst.length; i++) {
            if (filterFunc.apply(lst[i], [lst[i], i]))
                res.push(lst[i]);
        }
        return res;
    }
}

function _check(check, func) {
    if (check)
        console.log(func + ' check:pass');
    else
        console.error(func + ' check:failed');
    return check;
}
function _log(log) {
    if (typeof(console)!='undefined')
        console.log(log);
    if (typeof(androidLog)!='undefined')
        androidLog(log);
}
function isArray(o) {
    return Object.prototype.toString.call(o) == '[object Array]';
}

function timepiece() {
    var dt = new Date();
    this.reset = function () {
        dt = new Date();
    }
    this.check = function () {
        var dt2 = new Date();
        return ((dt2.getTime() - dt.getTime()) * 1.0) / 1000;
    }
    this.show = function (msg) {
        var res = this.check();
        console.log('time spent: ' + res + 's ' + (msg || ''));
    }
    return this;
}

function ExecQueue() {
    this.locked = 0;
    var base = this;
    var queue = [];
    this.lock = function () {
        base.locked = 1;
    }
    this.push = function (fun, args) {
        queue.push([fun, args]);
    }
    this.release = function () {
        base.locked = 0;
        if (queue.length) {
            var info = queue.shift();
            info[0].apply(this, info[1]);
        }
    }
    this.fixCallBack = function (callback) {
        return function () {
            callback.apply(this, arguments);
            base.locked = 0;
            if (queue.length) {
                var info = queue.shift();
                info[0].apply(this, info[1]);
            }
        };
    }
}
